package com.spukmk3me.io.userinput;

import com.spukmk3me.math.FPMath;

/**
 *  Preprocess input for pointer.
 *
 */
public class PointerInput
{
    public PointerInput( int nButton )
    {
        m_buttonData    = new ButtonData[ nButton ];
        
        for ( int i = 0; i != nButton; ++i )
            m_buttonData[ i ] = new ButtonData( i );
        
        m_x = m_y = -1;
    }
    
    /**
     *  Do not call manually
     */
    public void process()
    {
        long time = System.currentTimeMillis();
        ButtonData data;
        
        for ( int i = 0; i != m_buttonData.length; ++i )
        {
            data = m_buttonData[ i ];
            data.m_time[ data.m_state ] = time - data.m_timeAtBeginState[ data.m_state ];
        }
    }
    
    /**
     *  Pointer X.
     *  @return
     */
    public int getX()
    {
        return m_x;
    }
    
    public int getY()
    {
        return m_y;
    }
    
    public float getSpeedX()
    {
        return (float)m_swipeSpeedX / 0x03E80000;
    }
    
    public int getSpeedX_int()
    {
        return m_swipeSpeedX;
    }
    
    public float getSpeedY()
    {
        return (float)m_swipeSpeedY / 0x03E80000;
    }
    
    public int getSpeedY_int()
    {
        return m_swipeSpeedY;
    }
    
    public int getDeltaX()
    {
        return m_deltaX;
    }
    
    public int getDeltaY()
    {
        return m_deltaY;
    }
    
    public ButtonData getButton( int id )
    {
        if ( (id < 0) || (id >= m_buttonData.length) )
            return null;
        
        return m_buttonData[ id ];
    }
    
    public final void pointerUp( int x, int y, int buttonID )
    {
        calculateTouchPosition( x, y );
        calculateSwipeSpeed();
        
        m_buttonData[ buttonID ].m_state = ButtonData.UP;
        m_buttonData[ buttonID ].m_time[ ButtonData.UP ] =
            m_buttonData[ buttonID ].m_time[ ButtonData.DOWN ] = 0;
        m_buttonData[ buttonID ].m_timeAtBeginState[ ButtonData.UP ] = System.currentTimeMillis();
    }
    
    public final void pointerDown( int x, int y, int buttonID )
    {
        m_swipeSpeedX = m_swipeSpeedY = 0;
        calculateTouchPosition( x, y );
        
        m_firstDownX = m_x;
        m_firstDownY = m_y;
        m_lastTouchTime = System.currentTimeMillis();
        
        m_buttonData[ buttonID ].m_state = ButtonData.DOWN;
        m_buttonData[ buttonID ].m_time[ ButtonData.UP ] =
            m_buttonData[ buttonID ].m_time[ ButtonData.DOWN ] = 0;
        m_buttonData[ buttonID ].m_timeAtBeginState[ ButtonData.DOWN ] = System.currentTimeMillis();
    }
    
    public final void pointerDragged( int x, int y )
    {
        calculateTouchPosition( x, y );
        calculateSwipeSpeed();
    }
    
    private void calculateTouchPosition( int x, int y )
    {
        m_deltaX = x - m_x;
        m_deltaY = y - m_y;
        m_x  = x;
        m_y  = y;
    }
    
    private void calculateSwipeSpeed()
    {
        int deltaTime = FPMath.fpDiv( (int)((System.currentTimeMillis() - m_lastTouchTime) << 16), 0x03E80000 );
        
        if ( deltaTime >= 500 )
        {
            m_swipeSpeedX = FPMath.fpDiv( m_x - m_firstDownX << 16, deltaTime );
            m_swipeSpeedY = FPMath.fpDiv( m_y - m_firstDownY << 16, deltaTime );
            
            //m_swipeSpeedX = Math.min( m_swipeSpeedX, (int)(MINSWIPESPEED / m_zoomX) );
            //m_swipeSpeedX = Math.max( m_swipeSpeedX, (int)(MAXSWIPESPEED / m_zoomX) );
            //m_swipeSpeedY = Math.min( m_swipeSpeedY, (int)(MINSWIPESPEED / m_zoomY) );
            //m_swipeSpeedY = Math.max( m_swipeSpeedY, (int)(MAXSWIPESPEED / m_zoomY) );
        }
        else
            m_swipeSpeedX = m_swipeSpeedY = 0;
    }
    
    private static final int MINSWIPESPEED = 0x00080000;
    private static final int MAXSWIPESPEED = 0x01000000;
    
    private ButtonData[]    m_buttonData;

    private long            m_lastTouchTime;
    
    private int             m_x, m_y, m_firstDownX, m_firstDownY;
    private int             m_swipeSpeedX, m_swipeSpeedY, m_deltaX, m_deltaY;
}